package com.gitee.huanminabc.jtimerwheel.utils;


import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 */
@Slf4j
public class TimerWheelDateUtil {

    //指定时间下周初的时间戳
    public static int getDateNextWeekStart(Date date) {
        long dateNextWeek = getDateNextWeek(date, 1);
        return (int) getDateStart(new Date(dateNextWeek));
    }

    //获取指定时间下一分钟的开始时间的日期时间戳
    public static int getDateNextMinute(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, 1);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //获取指定时间下一小时的开始时间的日期时间戳
    public static int getDateNextHour(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR_OF_DAY, 1);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //获取指定时间下一天的开始时间的日期时间戳
    public static int getDateNextDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //获取指定时间下一周的开始时间的日期时间戳,周一为一周的开始
    public static int getDateNextWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.WEEK_OF_YEAR, 1);
        cal.set(Calendar.DAY_OF_WEEK, 2);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //获取指定时间下一月的开始时间的日期时间戳
    public static int getDateNextMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //获取指定时间下一年的开始时间的日期时间戳
    public static int getDateNextYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, 1);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //返回中国的星期几 1~7
    public static int getWeekCn(int week) {
        int weekStr = 0;
        switch (week) {
            case 1:
                weekStr = 2;
                break;
            case 2:
                weekStr = 3;
                break;
            case 3:
                weekStr = 4;
                break;
            case 4:
                weekStr = 5;
                break;
            case 5:
                weekStr = 6;
                break;
            case 6:
                weekStr = 7;
                break;
            case 7:
                weekStr = 1;
                break;
        }
        return weekStr;

    }

    //将中国的星期几转换成英文的星期几
    public static int getWeekCnReversal(int week) {
        int weekStr = 0;
        switch (week) {
            case 1:
                weekStr = 7;
                break;
            case 2:
                weekStr = 1;
                break;
            case 3:
                weekStr = 2;
                break;
            case 4:
                weekStr = 3;
                break;
            case 5:
                weekStr = 4;
                break;
            case 6:
                weekStr = 5;
                break;
            case 7:
                weekStr = 6;
                break;
        }
        return weekStr;

    }


    //获取指定时间下个星期n的日期时间戳
    public static int getDateWeek(Date date, int week) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.WEEK_OF_YEAR, 1);
        cal.set(Calendar.DAY_OF_WEEK, getWeekCn(week));
        return (int) (cal.getTimeInMillis()/ 1000);
    }
    //获取指定时间下秒的开始时间的日期时间戳
    public static int getDateNextSecond(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.SECOND, 1);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }
    //指定时间加上年月日时分秒后的时间(不加的话就是0)
    public static Date addDate(Date date, int year, int month, int day, int hour, int minute, int second) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, year);
        cal.add(Calendar.MONTH, month);
        cal.add(Calendar.DAY_OF_MONTH, day);
        cal.add(Calendar.HOUR_OF_DAY, hour);
        cal.add(Calendar.MINUTE, minute);
        cal.add(Calendar.SECOND, second);
        return cal.getTime();
    }
    //日期转换成字符串
    public static String dateTurnString(Date date, TimerWheelDateEnum patt) {
        SimpleDateFormat sdf = new SimpleDateFormat(patt.getValue());
        return sdf.format(date);
    }

    //获取指定时间的毫秒数
    public static int getDateTimeMillis(Date date) {
        long l = date.getTime();
        //截取后三位
        String s = String.valueOf(l);
        String substring = s.substring(s.length() - 3);
        return Integer.parseInt(substring);
    }
    //获取指定时间的秒数
    public static int getDateTimeSecond(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.SECOND);
    }
    //获取当前时间分钟数
    public static int getDateTimeMinute(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MINUTE);
    }
    //获取当前时间小时数
    public static int getDateTimeHour(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.HOUR_OF_DAY);
    }
    //获取当前时间天数
    public static int getDateTimeDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_MONTH);
    }
    //获取当前时间月份
    public static int getDateTimeMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH) + 1;
    }
    //获取当前时间年份
    public static int getDateTimeYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.YEAR);
    }
    //获取当前时间星期几
    public static int getDateTimeWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int i = cal.get(Calendar.DAY_OF_WEEK);
        return  getWeekCn(i);
    }

    //获取当前时间戳秒级别
    public static int getDateTimeSecond() {
        return (int) (System.currentTimeMillis()/ 1000);
    }


    //秒时间戳转换成日期
    public static Date secondTurnDate(long second) {
        //判断是否是10位
        if (String.valueOf(second).length() == 10) {
            second = second * 1000;
        }
        return new Date(second);
    }

    //当前日期  返回Date对象
    public static Date date() {
        return new Date();
    }

    //指定时间添加秒,分,时,天,月,年,星期, 24小时   timestamp  时间戳  second 秒
    public static int addDateTimestamp(long timestamp, int second, int minute, int hour, int day, int month, int year, int week) {
        return (int) (timestamp + second + minute * 60L + hour * 3600L + day * 86400L + month * 2592000L + year * 31104000L +
                        week * 604800L);
    }


    //获取指定时间的开始时间的日期时间戳 (也就是指定时间的00:00:00)
    public static int getDateStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //获取指定时间的结束日期时间戳 (也就是指定时间的23:59:59)
    public static int getDateEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return (int) (cal.getTimeInMillis()/ 1000);
    }



    //获取指定时间下周的第几天 1~7
    public static int getDateNextWeek(Date date, int week) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        week = week + 1;
        if (week == 8) {
            week = 1;
        }
        cal.add(Calendar.WEEK_OF_YEAR, 1);
        cal.set(Calendar.DAY_OF_WEEK, week);
        return (int) (cal.getTimeInMillis()/ 1000);
    }


    //获取指定时间的下分钟结束时间的日期时间戳
    public static int getDateNextMinuteEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, 1);
        cal.set(Calendar.SECOND, 59);
        return (int) (cal.getTimeInMillis()/ 1000);
    }


    // 获取指定时间的下天结束时间的日期时间戳
    public static int getDateNextDayEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    // 获取指定时间的下周结束时间的日期时间戳
    public static int getDateNextWeekEnd(Date date) {
        long dateNextWeek = getDateNextWeek(date, 7);
        return getDateEnd(new Date(dateNextWeek));
    }

    // 获取指定时间的下月结束时间的日期时间戳 ,也就是下月的最后一天的23:59:59
    public static int getDateNextMonthEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, 2);
        cal.set(Calendar.DAY_OF_MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    // 获取指定时间的下年结束时间的日期时间戳  ,也就是下年的最后一天的23:59:59
    public static int getDateNextYearEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, 2);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    //计算两个时间戳的时间差(返回秒)
    public static int getTimeDifferenceSecond(long start_time, long end_time) {
        if (start_time == 0 || end_time == 0) {
            return 0;
        }
        if (start_time > end_time) {
            return (int) (start_time - end_time);
        } else {
            return (int) (end_time - start_time);
        }
    }


    //设置秒
    public static int setSecond(Date date, int second) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.SECOND, second);
        return (int) (cal.getTimeInMillis()/ 1000);
    }


    public static int setMinute(Date currentDate, int minute) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(currentDate);
        cal.set(Calendar.MINUTE, minute);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    public static int setHour(Date currentDate, int hour) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(currentDate);
        cal.set(Calendar.HOUR_OF_DAY, hour);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    public static int setDay(Date currentDate, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(currentDate);
        cal.set(Calendar.DAY_OF_MONTH, day);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    public static int setMonth(Date currentDate, int month) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(currentDate);
        cal.set(Calendar.MONTH, month);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    public static int setYear(Date currentDate, int year) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(currentDate);
        cal.set(Calendar.YEAR, year);
        return (int) (cal.getTimeInMillis()/ 1000);
    }

    public static int setWeek(Date currentDate, int week) {
        week= getWeekCnReversal(week);
        Calendar cal = Calendar.getInstance();
        cal.setTime(currentDate);
        cal.set(Calendar.DAY_OF_WEEK, week);
        return (int) (cal.getTimeInMillis()/ 1000);
    }
}
